#!/usr/bin/python

import NSObject
import DerbyXML
import logging

nsoLogger = logging.getLogger("NSO")

# these are explicit states that can be compared against
# provide an easy way to check the bout state

PREBOUT = 0  # the bout hasn't started yet (we are before the start time)
PENDING = 1  # we have reach the bell time, but haven't started yet
INTERMISSION = 2  # in an intermission

JAM_IS_ON = 10  # jam has started
LINEUP = 11  # waiting for lineup

OFFICIAL_TIMEOUT = 20
TEAM_TIMEOUT = 21
OFFICIAL_REVIEW_TIMEOUT = 22
INJURY = 23
POST_TIMEOUT_LINEUP = 30  # the "up to 30 seconds" after a timeout

OVERTIME = 50
FINAL = 51  # unofficial final - switch to "completed" when done

COMPLETED = 100  # bout is completed, score is final

BoutStateStrings = {
    PREBOUT: "Prebout",
    PENDING: "Pending",
    INTERMISSION: "Intermission",
    JAM_IS_ON: "Jam Is On",
    LINEUP: "Lineup",
    OFFICIAL_TIMEOUT: "Official Timeout",
    TEAM_TIMEOUT: "Team Timeout",
    OFFICIAL_REVIEW_TIMEOUT: "Official Review",
    INJURY: "Injury",
    POST_TIMEOUT_LINEUP: "Post Timeout Lineup",
    OVERTIME: "Overtime",
    FINAL: "Final",
    COMPLETED: "Completed"
}


def ShouldPeriodClockRun(state):
    return state in [JAM_IS_ON, LINEUP]


def ShouldTimeoutClockRun(state):
    return state in range(OFFICIAL_TIMEOUT, INJURY)


def ShouldJamClockRun(state):
    return state == JAM_IS_ON


def ShouldIntermissionClockRun(state):
    return state == INTERMISSION


def ShouldTimeToDerbyClockRun(state):
    return state == PREBOUT


def ShouldUnofficialFinalShow(state):
    return state == FINAL


def ShouldOfficialFinalShow(state):
    return state == COMPLETED


def ShouldOvertimeShow(state):
    return state == OVERTIME


def ShouldLineupClockRun(state):
    return state in [LINEUP, POST_TIMEOUT_LINEUP]


class BoutState(NSObject.NSObject):
    def __init__(self, dxml):
        super(BoutState, self).__init__()
        self.derbyXML = dxml
        self.boutState = PREBOUT
        self.homeScore = 0
        self.awayScore = 0
        self.homeHasLead = False
        self.awayHasLead = False
        self.homeLineup = {}
        self.awayLineup = {}
        self.homeTimeoutsUsed = 0
        self.awayTimeoutsUsed = 0
        self.homeOfficialReviewsUsed = 0
        self.awayOfficialReviewsUsed = 0
        self.periodNumber = 0
        self.jamNumber = 0
        # "Current" is the one about to happen, "active" is the one that is actually running (or has just completed)
        self.currentJam = None
        self.currentPeriod = None
        self.activeJam = None
        self.activePeriod = None
        self.activeTimeout = None

    def UpdatePeriods(self):
        periods = self.derbyXML.periods()
        active = None
        pnum = 0
        for period in periods:
            if period.timestamp is None:
                continue  # this can't be the current one, no timestamp yet
            pnum += 1
            active = period
        if active is None:  # not started, use first period
            self.periodNumber = 1
            self.activePeriod = None
            self.currentPeriod = periods[0]
            return periods[0]
        else:
            self.activePeriod = active
            self.currentPeriod = active
            self.periodNumber = pnum
            return active

    def UpdateJam(self):
        period = self.UpdatePeriods()
        jnum = 0
        active = None
        current = None
        activeNum = 0
        currentNum = 0
        for child in period.children:
            if child.elementName == "jam":
                jnum += 1
                current = child
                currentNum = jnum
                if child.timestamp:
                    active = child
                    activeNum = jnum
                else:
                    active = None
        if active:
            self.jamNumber = activeNum
            self.activeJam = active
            self.currentJam = active
            return active
        elif current:
            self.jamNumber = currentNum
            self.activeJam = None
            self.currentJam = current
            return current
        else:
            self.jamNumber = 1
            self.activeJam = None
            self.currentJam = None
            return None

    def UpdateTimeout(self):
        period = self.UpdatePeriods()
        retval = None
        for child in period.children:
            if child.elementName == "time-out" or child.elementName == "official-review":
                if child.timestamp:
                    retval = child
                elif retval is None:
                    retval = child  # better than nothing

    def UpdateBoutState(self, xml):
        oldState = self.boutState
        newState = xml.UpdateBoutState(self.boutState)
        if oldState != newState:
            self.boutState = newState
            nsoLogger.info("Bout State:" + BoutStateStrings[self.boutState])
        if xml.elementName == 'period':
            self.UpdatePeriods()  # update period number
        elif xml.elementName == 'jam':
            self.UpdateJam()  # update jam number
        elif xml.elementName == 'pass':
            totals = {
                self.derbyXML.teams()[0]['id']: 0,
                self.derbyXML.teams()[1]['id']: 0,
            }
            for p in self.derbyXML.periods():
                for j in p.jams():
                    for passes in j.passes():
                        totals[passes["team"]] += int(passes['points'])
            self.homeScore = totals[self.derbyXML.teams()[0]['id']]
            self.awayScore = totals[self.derbyXML.teams()[1]['id']]
            
    